package com.cskaoyan.service;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.user.Address;
import com.cskaoyan.bean.wx_search.UserIndex;
import com.cskaoyan.bean.zhao_order_bean.OrderGoods;
import com.cskaoyan.bean.zhao_order_bean.*;
import com.cskaoyan.mapper.*;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * <h3>market</h3>
 *
 * @author:Zhao
 * @date:2021-10-18 20:10:14
 * @description:
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    OrderGoodsMapper orderGoodsMapper;

    @Autowired
    AddressMapper addressMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    CartMapper cartMapper;

    @Autowired
    SystemConfigMapper systemConfigMapper;

    @Autowired
    GoodsProductMapper goodsProductMapper;

    @Autowired
    CouponUserMapper couponUserMapper;


    @Override
    public BasePageData query(Integer userId, String orderSn, Date start,
                              Date end, BaseParam param) {

        //配置分页信息 → 在执行预编译过程，会帮你拼接分页的sql语句
        PageHelper.startPage(param.getPage(), param.getLimit());

        OrderExample example = new OrderExample();

        //构造条件 → List<Criterion> → and方法做的事情就是构造一个Criterion的对象添加到List里
        //如果username不为null，拼接条件 and username like '%songge%'
        OrderExample.Criteria criteria = example.createCriteria();
        if (userId != null && !"".equals(userId)) {
            criteria.andUserIdEqualTo(userId);
        }
        if (orderSn != null && !"".equals(orderSn)) {
            criteria.andOrderSnEqualTo(orderSn);
        }
        //无论订单是否完成，都有订单的创建时间，以此为标准查询
        if (start != null && !"".equals(start)) {
            criteria.andAddTimeBetween(start, end);
        }

        //.andPasswordBetween("niupi","buniupi");
        //设置排序
        example.setOrderByClause(param.getSort() + " " + param.getOrder());
        List<Order> orders = orderMapper.selectByExample(example);
//        orderMapper.updateByExampleSelective(example);
        return BasePageData.ok(orders);
    }

    @Override
    //需根据订单id查到订单内容，商品列表，用户信息

    public DetailBasePageData detail(Integer id) {

        //精准查询，无需分页
        OrderExample example = new OrderExample();
        OrderExample.Criteria criteria = example.createCriteria();

        criteria.andIdEqualTo(id);

        //直接在订单表中查订单
        Order order = orderMapper.selectByPrimaryKey(id);
        //订单表中有userId，可据此查用户

        Integer userId = order.getUserId();
        User user = userMapper.selectByPrimaryKey(userId);

        //怎么查商品？有一张order_goods表，可通过订单id查询
//        List<OrderGoods> orderGoods = (List<OrderGoods>) orderGoodsMapper.selectByPrimaryKey(id);
        orderGoodsMapper.selectByPrimaryKey(id);
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteriaOrderGoods = orderGoodsExample.createCriteria();
        criteriaOrderGoods.andOrderIdEqualTo(order.getId());

        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);


        DetailBasePageData detailBasePageData = DetailBasePageData.ok(order, orderGoods, user);
        return detailBasePageData;
    }

    @Override
    public void ship(Integer orderId, String shipChannel, String shipSn) {
        //根据id修改订单状态

        orderMapper.ship(orderId, shipChannel, shipSn);
    }

    @Override
    public void delete(Integer orderId) {

        orderMapper.delete(orderId);
    }

    @Override
    public void refund(Integer orderId) {

        orderMapper.refund(orderId);
    }

    @Override
    public BasePageData wxQuery(Short showType, BaseParam param) {
        Integer userId = getUserId();
        //配置分页信息 → 在执行预编译过程，会帮你拼接分页的sql语句
        PageHelper.startPage(param.getPage(), param.getLimit());

        OrderExample example = new OrderExample();
        OrderExample.Criteria criteria = example.createCriteria();

        /*
         * 前端：showType :0(全部) 1待付 2待发 3待收 4待评
         * 数据库：order_status : 101未付 201已付（待发）301已发（待收） 401、402已收（待评）
         *   TODO 401、402？？
         * */
        if (showType == 0) {
            showType = null;
        } else if (showType == 1) {
            showType = 101;
        } else if (showType == 2) {
            showType = 201;
        } else if (showType == 3) {
            showType = 301;
        } else if (showType == 4) {
            showType = 401;
        }

        if (showType != null && !"".equals(showType)) {
            criteria.andOrderStatusEqualTo(showType);
        }

        example.setOrderByClause(param.getSort() + " " + param.getOrder());

//        List<Order> orders = orderMapper.selectByExample(example);//此处返回的对象需同前端响应一致(不能用此方法)

        List<WxOrderListVO> wxOrderListVOS = orderMapper.selectWxOrderListVOS(showType ,userId);

        for (WxOrderListVO wxOrderListVO : wxOrderListVOS) {
            List<GoodsListEntity> goodsListEntityList = orderGoodsMapper.selectGoodsList(wxOrderListVO.getId());
            wxOrderListVO.setGoodsList(goodsListEntityList);
        }


        /*list: [{orderStatusText: "未付款", aftersaleStatus: 0, isGroupin: false, orderSn: "20211021477506",…},…]
            0: {orderStatusText: "未付款", aftersaleStatus: 0, isGroupin: false, orderSn: "20211021477506",…}
                actualPrice: 7997
                aftersaleStatus: 0
                goodsList: [,…]
                handleOption: {cancel: true, delete: false, pay: true, comment: false, confirm: false, refund: false, rebuy: false,…}
                id: 37
                isGroupin: false
                orderSn: "20211021477506"
                orderStatusText: "未付款"*/

        return BasePageData.ok(wxOrderListVOS);
    }

    public Integer getUserId(){
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        return user.getId();
    }

    @Override
    public void cancel(Integer orderId) {
        orderMapper.cancel(orderId);
    }

    @Override
    public OrderInfoVO wxDetail(Integer orderId) {
//        OrderInfoVO orderInfoVO = orderMapper.wxDetail(orderId);
        OrderInfoVO orderInfoVO = new OrderInfoVO();

        OrderInfoEntity orderInfo = orderMapper.selectOrderInfo(orderId);

        List<OrderGoods> orderGoods = orderGoodsMapper.selectOrderGoods(orderId);

        orderInfoVO.setOrderInfo(orderInfo);
        orderInfoVO.setOrderGoods(orderGoods);
        return orderInfoVO;
    }

    //changed by zhao 不显示逻辑删除的
    @Override
    public UserIndex selectOrderStatusNumByUserId(Integer userId) {
        OrderExample orderExample1 = new OrderExample();
        OrderExample.Criteria criteria1 = orderExample1.createCriteria();
        
        OrderExample orderExample2 = new OrderExample();
        OrderExample.Criteria criteria2 = orderExample2.createCriteria();
        
        OrderExample orderExample3 = new OrderExample();
        OrderExample.Criteria criteria3 = orderExample3.createCriteria();
        
        OrderExample orderExample4 = new OrderExample();
        OrderExample.Criteria criteria4 = orderExample4.createCriteria();
        if (userId != null){
            //待付款
            criteria1.andUserIdEqualTo(userId);
            criteria1.andOrderStatusEqualTo(((short) 101));
            criteria1.andDeletedEqualTo(false);

            //待发货
            criteria2.andUserIdEqualTo(userId);
            criteria2.andOrderStatusEqualTo(((short) 201));
            criteria2.andDeletedEqualTo(false);


            //待收货
            criteria3.andUserIdEqualTo(userId);
            criteria3.andOrderStatusEqualTo(((short) 301));
            criteria3.andDeletedEqualTo(false);


            //待评价
            criteria4.andUserIdEqualTo(userId);
            criteria4.andOrderStatusBetween((short)401,(short)402);
            criteria4.andDeletedEqualTo(false);

        }

        long unpaid = orderMapper.countByExample(orderExample1);
        long unship = orderMapper.countByExample(orderExample2);
        long unrecv = orderMapper.countByExample(orderExample3);
        long uncomment = orderMapper.countByExample(orderExample4);

        UserIndex.OrderInfo orderInfo = new UserIndex.OrderInfo();
        orderInfo.setUnpaid(((int) unpaid));
        orderInfo.setUnship(((int) unship));
        orderInfo.setUnrecv(((int) unrecv));
        orderInfo.setUncomment(((int) uncomment));

        UserIndex userIndex = new UserIndex();
        userIndex.setOrder(orderInfo);

        return userIndex;
    }

    //在购物车中提交订单
    //请求
    //addressId: 10 //地址id，根据地址表查找地址和userId，填入订单
    //cartId: 0 // 购物车id，暂不知何意（获取数量、规格？）
    //couponId: 0 //优惠券id，根据优惠券表查找，将优惠金额放入订单
    //grouponLinkId: 0
    //grouponRulesId: 0
    //message: "" //提交订单时可填写留言，直接放入订单中
    //userCouponId: TODO 暂不知何意 查看优惠券状态？
    // 响应
    //grouponLinkId: 0
    //orderId: 94
    @Override
    @Transactional
    public int submit(SubmitBO submitBO) {
        Address address = addressMapper.selectByPrimaryKey(submitBO.getAddressId());
        int cartId = submitBO.getCartId();
        if (cartId != 0) {
            Cart cart = cartMapper.selectByPrimaryKey(submitBO.getCartId());
            Integer productId = cart.getProductId();
            GoodsProduct goodsProduct = goodsProductMapper.selectByPrimaryKey(productId);
            if (goodsProduct.getNumber() < cart.getNumber()) {
                return -1;
            }

            //添加至订单表
            int orderId = addOrder(submitBO, cart.getPrice(), address);


            int affectedRowsOrderGoods = addOrderGoods(cart, orderId);

            cartMapper.updateDeletedById(cartId);

            //修改规格表库存
            goodsProductMapper.updateNumberById(productId, goodsProduct.getNumber() - cart.getNumber());
            if (orderId != 0 && affectedRowsOrderGoods > 0) {
                return orderId;
            }
        }

        CartExample cartExample = new CartExample();
        CartExample.Criteria cartCriteria = cartExample.createCriteria();
        cartCriteria.andCheckedEqualTo(true);
        cartCriteria.andUserIdEqualTo(address.getUserId());
        cartCriteria.andDeletedEqualTo(false);
        List<Cart> carts = cartMapper.selectByExample(cartExample);

        int totalPrice = 0;
        for (Cart cart : carts) {
            Integer id = cart.getId();
            cartMapper.updateDeletedById(id);
            int singleGoodsPrice = cart.getPrice().intValue();
            int goodsPrice = singleGoodsPrice * cart.getNumber();
            totalPrice += goodsPrice;
        }

        int orderId = addOrder(submitBO, BigDecimal.valueOf(totalPrice), address);

        int affectedRowsOrderGoods = 0;
        for (Cart cart : carts) {
            Integer productId = cart.getProductId();
            GoodsProduct goodsProduct = goodsProductMapper.selectByPrimaryKey(productId);
            if (goodsProduct.getNumber() < cart.getNumber()) {
                return -1;
            }

            //添加到ordergoods表
            affectedRowsOrderGoods = addOrderGoods(cart, orderId);

            goodsProductMapper.updateNumberById(productId, goodsProduct.getNumber() - cart.getNumber());
        }

        if (orderId != 0 && affectedRowsOrderGoods > 0) {
            return orderId;
        }

        return 0;

    }

    private int addOrderGoods(Cart cart, int orderId) {
        OrderGoods orderGoods = new OrderGoods();

        orderGoods.setOrderId(orderId);
        orderGoods.setGoodsId(cart.getGoodsId());
        orderGoods.setGoodsName(cart.getGoodsName());
        orderGoods.setGoodsSn(cart.getGoodsSn());
        orderGoods.setProductId(cart.getProductId());


        int number = cart.getNumber();
        orderGoods.setNumber((short)number);
        orderGoods.setPrice(cart.getPrice());
        orderGoods.setSpecifications(cart.getSpecifications());

        BeanUtils.copyProperties(cart, orderGoods);
        orderGoods.setId(null);
        orderGoods.setComment(0);

        return orderGoodsMapper.insert(orderGoods);
    }

    private int addOrder(SubmitBO submitBO, BigDecimal price, Address address) {
        //添加至订单表
        Order order = new Order();

        order.setUserId(address.getUserId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = simpleDateFormat.format(new Date());
        String orderSn = date.replaceAll("-", "").replaceAll(" ", "").replaceAll(":", "");

        order.setOrderSn(orderSn);
        order.setConsignee(address.getName());
        order.setMobile(address.getTel());
        order.setAddress(address.getAddressDetail());
        order.setMessage(submitBO.getMessage());
        order.setGoodsPrice(price);
        order.setComments((short) 0);
        order.setOrderStatus((short) 101);
        order.setCouponPrice(BigDecimal.valueOf(0));
        order.setIntegralPrice(BigDecimal.valueOf(0));
        order.setGrouponPrice(BigDecimal.valueOf(0));

        //获得运费信息
        SystemConfig configFreight = systemConfigMapper.selectByPrimaryKey(8);
        SystemConfig configMin = systemConfigMapper.selectByPrimaryKey(6);

        String keyValue = configFreight.getKeyValue();
        int freight = Integer.parseInt(keyValue);

        //消费总额大于min时免运费
        if (price.intValue() > Integer.parseInt(configMin.getKeyValue())) {
            freight = 0;
        }
        //查询优惠券表，处理优惠订单实际价格
        int couponId = submitBO.getCouponId();
        int actualPrice = price.intValue() + freight;
        order.setFreightPrice(BigDecimal.valueOf(freight));

        if (couponId != -1 && couponId != 0) {
            Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
            BigDecimal discount = coupon.getDiscount();
            order.setCouponPrice(discount);
            int couponPrice = discount.intValue() * coupon.getLimit();//每次使用优惠券的数量 todo
            actualPrice = actualPrice - couponPrice;
        }

        order.setOrderPrice(BigDecimal.valueOf(actualPrice));
        order.setActualPrice(BigDecimal.valueOf(actualPrice));

        order.setPayTime(new Date());
        order.setAddTime(new Date());
        order.setUpdateTime(new Date());
        int orderAffectedRows = orderMapper.insertSelective(order);
        Integer orderId = order.getId();

        if (couponId != -1 && couponId != 0) {
            //将优惠券和用户关联起来
            int id = couponUserMapper.selectIdByCouponId(couponId, address.getUserId());
            CouponUser couponUser = new CouponUser();

            couponUser.setId(id);
            couponUser.setStatus((short) 1);
            couponUser.setOrderId(orderId);
            couponUser.setUpdateTime(new Date());
            couponUserMapper.updateByPrimaryKeySelective(couponUser);
        }
        if (orderAffectedRows == 1) {
            return orderId;
        }
        return 0;
    }

    @Override
    public void prepay(Integer orderId) {
        orderMapper.prepay(orderId);
    }

    @Override
    public void wxRefund(Integer orderId) {
        orderMapper.wxRefund(orderId);
    }

    @Override
    public void confirm(Integer orderId) {
        orderMapper.confirm(orderId);
    }

    @Override
    public OrderGoods selectInfoGood(Integer orderId, Integer goodsId) {
        OrderGoodsExample example = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = example.createCriteria();
        if (orderId == null || goodsId == null)
            return null;
        criteria.andOrderIdEqualTo(orderId);
        criteria.andGoodsIdEqualTo(goodsId);

        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(example);
        if (orderGoods != null)
            return orderGoods.get(0);
        return null;
    }

}
